package com.vadmin.vadminjava.common;


import com.alibaba.fastjson.JSONObject;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.*;
import java.util.concurrent.ThreadLocalRandom;

/* ***********************************************************
 *
 * 微信卡券相关工具方法
 *
 * **********************************************************/
@Component
public class WxCouponUtils {

	public static String WeCouponAppid = "wx35839eba72c12a73";
	public static String WeCouponSecret = "wx35839eba72c12a73";
	//////////////////////////////商户平台，发放卡卷代码

	//公众号appid
	public static String GzhAPPID = "wx35839eba72c12a73";
	//商户信息
	public static String MCH_ID = "1622221291";
	public static String MCH_KEY = "55b4908f6802c82f96c0280599fac33e";
	public static String APIV3_KEY="465b4f13983421044fd58236be0f1aef"; //商户平台上的APIV3密钥

	//证书信息
	public static String SERIAL_NO = "433BEF4E0A8669922F635E624AAE185E58EA839F";

	@Value ("${KEY_PATH}")
	public  String KEY_PATH;


	public static String getRfc3339(Date date) {
		DateTime rfc3339Date = new DateTime(date, DateTimeZone.forTimeZone(TimeZone.getTimeZone("Asia/Shanghai")));
		return rfc3339Date.toString();
	}


	//转分，这什么蓝交？？
	public static int zhuanFen(Object num) {
		return BigDecimalUtils.mul(num, 100).toBigInteger().intValue();
	}


	//签啥名？
	public static String sign(String[] str) {
		System.out.println(Arrays.asList(str));
		Arrays.sort(str);
		String string = new String();
		for (int i = 0; i < 4; i++) {
			string += str[i];
		}
		String signature = null;    //加密结果
		signature = getSha1(string);  //Sha1加密
		return signature;
	}

	//Sha1加密
	public static String getSha1(String str) {
		if (str == null || str.length() == 0) {
			return null;
		}
		char hexDigits[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
		                    'a', 'b', 'c', 'd', 'e', 'f'};
		try {
			MessageDigest mdTemp = MessageDigest.getInstance("SHA1");
			mdTemp.update(str.getBytes("UTF-8"));

			byte[] md = mdTemp.digest();
			int j = md.length;
			char buf[] = new char[j * 2];
			int k = 0;
			for (int i = 0; i < j; i++) {
				byte byte0 = md[i];
				buf[k++] = hexDigits[byte0 >>> 4 & 0xf];
				buf[k++] = hexDigits[byte0 & 0xf];
			}
			return new String(buf);
		} catch (Exception e) {
			// TODO: handle exception
			return null;
		}
	}

	public static Map<String, Object> objectToMap(Object obj) {
		String jsonStr = JSONObject.toJSONString(obj);
		return JSONObject.parseObject(jsonStr);
	}

	public static String getAsciiSort(Map<String, Object> map) {
		List<Map.Entry<String, Object>> infoIds = new ArrayList<Map.Entry<String, Object>>(map.entrySet());
		// 对所有传入参数按照字段名的 ASCII 码从小到大排序（字典序）
		Collections.sort(infoIds, new Comparator<Map.Entry<String, Object>>() {
			@Override
			public int compare(Map.Entry<String, Object> o1, Map.Entry<String, Object> o2) {
				return ((String) o1.getKey()).compareToIgnoreCase((String) o2.getKey());
			}
		});

		// 构造签名键值对的格式
		StringBuilder sb = new StringBuilder();
		for (Map.Entry<String, Object> item : infoIds) {
			if (item.getKey() != null || item.getKey() != "") {
				String key = item.getKey();
				String val = item.getValue().toString();
				if (!(val == "" || val == null)) {
					sb.append(key + "=" + val + "&");
				}
			}
		}
		return sb.toString();
	}

	/**
	 * 将加密后的字节数组转换成字符串
	 *
	 * @param b 字节数组
	 * @return 字符串
	 */
	public static String byteArrayToHexString(byte[] b) {
		StringBuilder hs = new StringBuilder();
		String stmp;
		for (int n = 0; b != null && n < b.length; n++) {
			stmp = Integer.toHexString(b[n] & 0XFF);
			if (stmp.length() == 1)
				hs.append('0');
			hs.append(stmp);
		}
		return hs.toString().toLowerCase();
	}

	/**
	 * 构造package
	 *
	 * @param params
	 * @return
	 * @throws UnsupportedEncodingException
	 */
	public static String createSign(Map<String, String> params) throws UnsupportedEncodingException {
		Set<String> keysSet = params.keySet();
		Object[] keys = keysSet.toArray();
		Arrays.sort(keys);
		StringBuffer temp = new StringBuffer();
		boolean first = true;
		for (Object key : keys) {
			if (first) {
				first = false;
			} else {
				temp.append("&");
			}
			temp.append(key.toString()).append("=");
			Object value = params.get(key);
			String valueString = "";
			if (null != value) {
				valueString = value.toString();
			}
			temp.append(valueString);
		}
		return temp.toString();
	}

	/**
	 * HmacSHA256类型签名
	 *
	 * @param map
	 * @return
	 * @throws UnsupportedEncodingException
	 * @throws NoSuchAlgorithmException
	 * @throws InvalidKeyException
	 */
	public static String paySignDesposit(Map<String, Object> map, String key) throws UnsupportedEncodingException, NoSuchAlgorithmException, InvalidKeyException {
		Map<String, String> params = new HashMap<String, String>();
		Set<String> set = map.keySet();
		for (String string : set) {
			if (!map.get(string).equals("")) {
				params.put(string, String.valueOf(map.get(string)));
			}
		}
		String string1 = createSign(params);
		String stringSignTemp = string1 + "&key=" + key;
		System.out.println(stringSignTemp);
		//return DigestUtils.sha256Hex(stringSignTemp).toUpperCase();
		Mac           sha256_HMAC = Mac.getInstance("HmacSHA256");
		SecretKeySpec secret_key  = new SecretKeySpec(key.getBytes(), "HmacSHA256");
		sha256_HMAC.init(secret_key);
		//  utf-8 : 解决中文加密不一致问题,必须指定编码格式
		return byteArrayToHexString(sha256_HMAC.doFinal(stringSignTemp.getBytes("utf-8"))).toUpperCase();
	}

	// 拼凑商家卷请求需要的请求数据
	public static String requestJsonGenerate(JSONObject coupon) {
		// 面额和门槛(单位都是分)

		// 这个值可以随意创建，只要保证唯一即可（不用在意我的创建方法）
		// 商户创建批次凭据号（格式：商户id+日期+流水号），可包含英文字母，数字，|，_，*，-等内容，不允许出现其他不合法符号，商户侧需保持唯一性 (9856886520200811174644kk6tclE)
		String outRequestNo = System.currentTimeMillis() + ThreadLocalRandom.current().nextInt(100000) + "";

		//"  \"available_begin_time\":\"" + getRfc3339(coupon.getDate("beginTimestamp")) + "\",\n" +
		//"  \"available_end_time\":\"" + getRfc3339(coupon.getSqlDate("ndTimestamp")) + "\",\n" +

		String info = "{\n" +
				"  \"stock_name\":\"" + coupon.getString("stockName") + "\",\n" +
				"  \"belong_merchant\":\"" + MCH_ID + "\",\n" +
				"  \"comment\": \"活动使用\",\n" +
				"  \"goods_name\": \"活动使用\",\n" +
				"  \"stock_type\": \"NORMAL\",\n" +
				"  \"coupon_use_rule\": {\n" +
				"    \"coupon_available_time\": {\n" +
				"  \"available_begin_time\":\"" + getRfc3339(coupon.getDate("beginTimestamp")) + "\",\n" +
				"  \"available_end_time\":\"" + getRfc3339(coupon.getSqlDate("endTimestamp")) + "\"\n" +
				"    },\n" +
				"    \"fixed_normal_coupon\": {\n" +
				"      \"discount_amount\": " + coupon.getString("couponAmount") + ",\n" +
				"      \"transaction_minimum\": " + coupon.getString("transactionMinimum") + "\n" +
				"    },\n" +
				"    \"use_method\": \"OFF_LINE\"\n" +
				"  },\n" +
				"  \"stock_send_rule\": {\n" +
				"    \"max_coupons\": " + coupon.getString("maxCoupons") + ",\n" +
				"    \"max_coupons_per_user\": " + coupon.getString("maxCouponsPerUser") + ",\n" +
				"    \"transferable\": false,\n" +
				"    \"shareable\": false\n" +
				"  },\n" +
				"  \"out_request_no\": \"" + outRequestNo + "\",\n" +
				"  \"display_pattern_info\": {\n" +
				"    \"description\": \"泉州卓恩家居\",\n" +
				"    \"merchant_name\": \"" + coupon.getString("merchantName") + "\",\n" +
				"    \"background_color\": \"Color020\"\n" +
				"  },\n" +
				"  \"notify_config\": {\n" +
				"    \"notify_appid\":\"" + coupon.getString("notifyAppid") + "\"\n" +
				"  },\n" +
				"  \"coupon_code_mode\": \"" + coupon.getString("couponCodeMode") + "\"\n" +
				"}";
		return info;

	}

}
